package com.frxuexi.lib_base

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.frxuexi.lib_base.entity.ApiResponse
import com.frxuexi.lib_base.entity.LocalDocEntity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import java.io.File

abstract class BaseViewModel<UiIntent:IUiIntent/*,UIState:UiState*/>:ViewModel() {
    private val _uiIntent= Channel<UiIntent>(Channel.UNLIMITED)

    private var _uiState= MutableStateFlow<UiState>(UiState.onLoading)
    val uiState:StateFlow<UiState>
        get() = _uiState

    init {
        viewModelScope.launch {
            _uiIntent.receiveAsFlow().collect{
                handleIntent(it)
            }
        }
    }

    /**
     * 处理意图
     */
    abstract fun handleIntent(it:UiIntent)

    /**
     * 发送意图
     */
    fun sendIntent(intent: UiIntent){
        viewModelScope.launch {
            _uiIntent.send(intent)
        }
    }

    /**
     * 网络请求
     */
    fun httpRequest(request: Flow<ApiResponse<Any>>, type: RequestType=RequestType.DEFAULT){
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO)
                .catch {
                    Log.i("===",it.message.toString())
                }
                .collect{ resp->
                    if(resp.statusCode==200){
                        _uiState.value=UiState.onSuccess(resp.data?:resp.datas,type)
                    }else{
                        _uiState.value=UiState.onError(resp.msg!!)
                    }
                }
        }
    }

    /**
     * room请求
     */
    fun roomRequest(request: Flow<Any>, type: RequestType=RequestType.DEFAULT){
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO)
                .catch {
                    Log.i("===",it.message.toString())
                }
                .collect{ resp->
                    if(resp!=null){
                        _uiState.value=UiState.onSuccess(resp,type)
                    }else{
                        _uiState.value=UiState.onError("操作失败")
                    }
                }
        }
    }

    /**
     * 下载apk
     */
    fun download(url:String,path:File){
        viewModelScope.launch {
            DownloadUtil.download(url, path = path)
                .flowOn(Dispatchers.IO)
                .catch {
                    Log.i("===",it.message.toString())
                }.collect{
                    _uiState.value=it
                }
        }
    }

    fun scanFiles(file:File){
        viewModelScope.launch {
            try {
                val files = file.listFiles()
                val list = mutableListOf<LocalDocEntity>()
                for (file in files){
                    list.add(LocalDocEntity(file.name,file.absolutePath))
                }
                _uiState.value=UiState.onSuccess(list,RequestType.SCAN)
            }catch (e:Exception){
                _uiState.value=UiState.onError(e.message.toString())
            }

        }


    }
}